package com.fx.ruankao.service.impl;

import com.fx.ruankao.entity.User;
import com.fx.ruankao.mapper.UserMapper;
import com.fx.ruankao.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import java.util.List;
import java.util.UUID;
import java.security.SecureRandom;
import java.util.Base64;

/**
 * 用户服务实现类
 */
@Service
@Transactional
public class UserServiceImpl implements UserService {
    
    @Autowired
    private UserMapper userMapper;
    
    @Override
    public int insert(User user) {
        // 设置创建时间
        user.setCreateTime(new java.util.Date());
        // 生成盐值并加密密码
        String salt = generateSalt();
        user.setSalt(salt);
        user.setPassword(encryptPassword(user.getPassword(), salt));
        return userMapper.insert(user);
    }
    
    @Override
    public int deleteById(Long id) {
        return userMapper.deleteById(id);
    }
    
    @Override
    public int update(User user) {
        return userMapper.update(user);
    }
    
    @Override
    public User selectById(Long id) {
        if (id == null) {
            throw new IllegalArgumentException("用户ID不能为空");
        }
        return userMapper.selectById(id);
    }
    
    @Override
    public List<User> selectAll() {
        return userMapper.selectList(new User());
    }
    
    @Override
    public User selectByUsername(String username) {
        return userMapper.selectByUsername(username);
    }
    
    @Override
    public List<User> selectByRoleId(Long roleId) {
        if (roleId == null) {
            throw new IllegalArgumentException("角色ID不能为空");
        }
        User user = new User();
        user.setRoleId(roleId);
        return userMapper.selectList(user);
    }
    
    @Override
    public User login(String username, String password) {
        User user = userMapper.selectByUsername(username);
        if (user != null) {
            // 使用加密方法验证密码
            String encryptedPassword = encryptPassword(password, user.getSalt());
            if (encryptedPassword.equals(user.getPassword())) {
                return user;
            }
        }
        return null;
    }
    
    @Override
    public boolean changePassword(Long userId, String oldPassword, String newPassword) {
        if (userId == null) {
            throw new IllegalArgumentException("用户ID不能为空");
        }
        User user = userMapper.selectById(userId);
        if (user != null) {
            // 验证旧密码
            String encryptedOldPassword = encryptPassword(oldPassword, user.getSalt());
            if (encryptedOldPassword.equals(user.getPassword())) {
                // 生成新的盐值并加密新密码
                String newSalt = generateSalt();
                user.setSalt(newSalt);
                user.setPassword(encryptPassword(newPassword, newSalt));
                return userMapper.update(user) > 0;
            }
        }
        return false;
    }
    
    @Override
    public boolean resetPassword(Long userId, String newPassword) {
        if (userId == null) {
            throw new IllegalArgumentException("用户ID不能为空");
        }
        User user = userMapper.selectById(userId);
        if (user != null) {
            // 生成新的盐值并加密新密码
            String newSalt = generateSalt();
            user.setSalt(newSalt);
            user.setPassword(encryptPassword(newPassword, newSalt));
            return userMapper.update(user) > 0;
        }
        return false;
    }
    
    @Override
    public int countUsers() {
        return userMapper.selectCount(new User());
    }
    
    /**
     * 密码加密方法 - 使用BCrypt算法替代MD5
     * @param password 原始密码
     * @param salt 盐值
     * @return 加密后的密码
     */
    private String encryptPassword(String password, String salt) {
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        // BCrypt内置了盐值管理，这里传入的salt仅用于系统逻辑
        return encoder.encode(password);
    }
    
    /**
     * 生成随机盐值
     * @return 盐值字符串
     */
    private String generateSalt() {
        SecureRandom random = new SecureRandom();
        byte[] saltBytes = new byte[16];
        random.nextBytes(saltBytes);
        return Base64.getEncoder().encodeToString(saltBytes);
    }
}